www.gusucode.com > VC++ 三维图形生成和察看工具 > VC++ 三维图形生成和察看工具/code/mesh/MeshDoc.cpp
//Download by http://www.NewXing.com // MeshDoc.cpp : implementation of the CMeshDoc class // #include "stdafx.h" #include "Mesh.h" #include "MeshDoc.h" #include "MainFrm.h" #include "ChildFrm.h" #include "DialogWmf.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMeshDoc IMPLEMENT_DYNCREATE(CMeshDoc, CDocument) BEGIN_MESSAGE_MAP(CMeshDoc, CDocument) //{{AFX_MSG_MAP(CMeshDoc) ON_COMMAND(ID_GL_ADD_WIREFRAME, OnGlAddWireframe) ON_UPDATE_COMMAND_UI(ID_GL_ADD_WIREFRAME, OnUpdateGlAddWireframe) ON_COMMAND(ID_GL_SMOOTH, OnGlSmooth) ON_UPDATE_COMMAND_UI(ID_GL_SMOOTH, OnUpdateGlSmooth) ON_COMMAND(ID_MESH_LOOP, OnMeshLoop) ON_UPDATE_COMMAND_UI(ID_MESH_LOOP, OnUpdateMeshLoop) ON_COMMAND(ID_GL_LIGHT, OnGlLight) ON_COMMAND(ID_GL_LINE, OnGlLine) ON_UPDATE_COMMAND_UI(ID_GL_LINE, OnUpdateGlLine) ON_UPDATE_COMMAND_UI(ID_GL_LIGHT, OnUpdateGlLight) ON_COMMAND(ID_GL_VERTEX, OnGlVertex) ON_UPDATE_COMMAND_UI(ID_GL_VERTEX, OnUpdateGlVertex) ON_COMMAND(ID_GL_FACE, OnGlFace) ON_UPDATE_COMMAND_UI(ID_GL_FACE, OnUpdateGlFace) ON_COMMAND(ID_MESH_COLOR_HEIGHT, OnMeshColorHeight) ON_COMMAND(ID_EDIT_WMF, OnEditWmf) ON_UPDATE_COMMAND_UI(ID_EDIT_WMF, OnUpdateEditWmf) ON_COMMAND(ID_GL_CULLING, OnGlCulling) ON_UPDATE_COMMAND_UI(ID_GL_CULLING, OnUpdateGlCulling) ON_COMMAND(ID_MESH_COLOR_CHOOSE, OnMeshColorChoose) ON_UPDATE_COMMAND_UI(ID_MESH_COLOR_CHOOSE, OnUpdateMeshColorChoose) ON_UPDATE_COMMAND_UI(ID_MESH_COLOR_HEIGHT, OnUpdateMeshColorHeight) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMeshDoc construction/destruction CMeshDoc::CMeshDoc() { m_AddWireframe = 0; m_Smooth = 0; m_PolygonOffset = -1.0f; m_Light = TRUE; m_Mode = GL_FILL; m_Culling = TRUE; } CMeshDoc::~CMeshDoc() { } BOOL CMeshDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CMeshDoc serialization void CMeshDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CMeshDoc diagnostics #ifdef _DEBUG void CMeshDoc::AssertValid() const { CDocument::AssertValid(); } void CMeshDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMeshDoc commands BOOL CMeshDoc::OnOpenDocument(LPCTSTR lpszPathName) { // Extension-based checking CString file = lpszPathName; // Extension CString extension = lpszPathName; extension = extension.Right(4); extension.MakeLower(); // Path "c:\path\file.wrl" -> c:\path CString path = lpszPathName; path = path.Left(path.ReverseFind('\\')); // CDocument SetCurrentDirectory(path); TRACE("\nOpening document\n"); TRACE("File : %s\n",lpszPathName); TRACE("Path : %s\n",path); TRACE("Extension : %s\n",extension); // Start reading VRML file if(extension == ".wrl") { TRACE("wrl type\n"); // Parser VRML 2.0 CParserVrml parser; if(parser.Run((char *)lpszPathName,&m_SceneGraph)) { m_SceneGraph.BuildAdjacency(); m_SceneGraph.CalculateNormalPerFace(); m_SceneGraph.CalculateNormalPerVertex(); m_SceneGraph.SetColorBinding(COLOR_PER_FACE); m_SceneGraph.SetNormalBinding(NORMAL_PER_FACE); return TRUE; } } return TRUE; } ////////////////////////////////////////////// ////////////////////////////////////////////// // RENDERING ////////////////////////////////////////////// ////////////////////////////////////////////// //*********************************************** // RenderScene //*********************************************** void CMeshDoc::RenderScene() { // Main drawing glPolygonMode(GL_FRONT_AND_BACK,m_Mode); if(m_Light) ::glEnable(GL_LIGHTING); else ::glDisable(GL_LIGHTING); m_SceneGraph.glDraw(); // Add wireframe (no light, and line mode) if(m_AddWireframe) { // Set state ::glDisable(GL_LIGHTING); ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); ::glEnable(GL_POLYGON_OFFSET_LINE); ::glPolygonOffset(m_PolygonOffset,-1.0f); // Draw again... m_SceneGraph.glDraw(TYPE_MESH3D); // Restore light and mode ::glDisable(GL_POLYGON_OFFSET_LINE); ::glEnable(GL_LIGHTING); } } //*********************************************** // Smooth subdivision //*********************************************** void CMeshDoc::OnMeshLoop() { BeginWaitCursor(); int NbObject = m_SceneGraph.NbObject(); for(int i=0;i<NbObject;i++) { CObject3d *pObject3d = m_SceneGraph[i]; if(pObject3d->GetType() == TYPE_MESH3D) { CMesh3d *pMesh = (CMesh3d *)pObject3d; pMesh->SubdivisionLoop(); } } UpdateAllViews(NULL); EndWaitCursor(); } void CMeshDoc::OnUpdateMeshLoop(CCmdUI* pCmdUI) { pCmdUI->Enable(m_SceneGraph.NbObject() > 0); } //********************************* // OnSaveDocument //********************************* BOOL CMeshDoc::OnSaveDocument(LPCTSTR lpszPathName) { // Extension CString extension = lpszPathName; extension = extension.Right(4); extension.MakeLower(); // Path "c:\path\file.wrl" -> c:\path CString path = lpszPathName; path = path.Left(path.ReverseFind('\\')); TRACE("\nSaving document\n"); TRACE("File : %s\n",lpszPathName); TRACE("Path : %s\n",path); TRACE("Extension : %s\n",extension); // Start reading VRML file if(extension == ".wrl") { TRACE("wrl type\n"); m_SceneGraph.SaveFile((char *)lpszPathName); } return TRUE; } //**************************** // Mode light //**************************** void CMeshDoc::OnGlLight() { m_Light = !m_Light; UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlLight(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Light); } //**************************** // Mode line //**************************** void CMeshDoc::OnGlLine() { m_Mode = GL_LINE; UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlLine(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Mode == GL_LINE); } //**************************** // Mode vertex //**************************** void CMeshDoc::OnGlVertex() { m_Mode = GL_POINT; UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlVertex(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Mode == GL_POINT); } //**************************** // Mode face //**************************** void CMeshDoc::OnGlFace() { m_Mode = GL_FILL; UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlFace(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Mode == GL_FILL); } //*********************************************** // Add wireframe //*********************************************** void CMeshDoc::OnGlAddWireframe() { m_AddWireframe = !m_AddWireframe; UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlAddWireframe(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_AddWireframe); } //*********************************************** // Smooth shading //*********************************************** void CMeshDoc::OnGlSmooth() { m_Smooth = !m_Smooth; if(m_Smooth) { m_SceneGraph.SetNormalBinding(NORMAL_PER_VERTEX); m_SceneGraph.SetColorBinding(COLOR_PER_VERTEX); ::glShadeModel(GL_SMOOTH); m_SceneGraph.BuildAdjacency(); } else { m_SceneGraph.SetNormalBinding(NORMAL_PER_FACE); m_SceneGraph.SetColorBinding(COLOR_PER_FACE); ::glShadeModel(GL_FLAT); m_SceneGraph.BuildAdjacency(); } UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlSmooth(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Smooth); } //********************************* // OnGlCulling //********************************* void CMeshDoc::OnGlCulling() { m_Culling = !m_Culling; if(m_Culling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); UpdateAllViews(NULL); } void CMeshDoc::OnUpdateGlCulling(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_Culling); } //********************************* // OnMeshColorHeight //********************************* void CMeshDoc::OnMeshColorHeight() { // Rainbow height ramp CColorRamp ramp; ramp.BuildRainbow(); ((CMesh3d *)m_SceneGraph.GetAt(0))->ColorHeight(&ramp); UpdateAllViews(NULL); } void CMeshDoc::OnUpdateMeshColorHeight(CCmdUI* pCmdUI) { int enable = FALSE; if(m_SceneGraph.NbObject()) if(m_SceneGraph.GetAt(0)->GetType() == TYPE_MESH3D) enable = TRUE; pCmdUI->Enable(enable); } //********************************* // GetView //********************************* CView *CMeshDoc::GetView() { CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd; // Get the active MDI child window. CMDIChildWnd *pChild = pFrame->MDIGetActive(); // Get the active view attached to the active MDI child // window. return pChild->GetActiveView(); } //********************************* // OnEditWmf //********************************* void CMeshDoc::OnEditWmf() { CDialogWmf dlg(NULL,this); dlg.DoModal(); } void CMeshDoc::OnUpdateEditWmf(CCmdUI* pCmdUI) { pCmdUI->Enable(m_SceneGraph.NbObject() > 0); } //********************************* // OnMeshColorChoose //********************************* void CMeshDoc::OnMeshColorChoose() { CColorDialog dlg; if(dlg.DoModal() == IDOK) { COLORREF color = dlg.GetColor(); unsigned char r = GetRValue(color); unsigned char g = GetGValue(color); unsigned char b = GetBValue(color); unsigned int NbObject = m_SceneGraph.NbObject(); for(unsigned int i=0; i<NbObject; i++) { CObject3d *pObject3d = m_SceneGraph.GetAt(i); if(pObject3d->GetType() == TYPE_MESH3D) ((CMesh3d *)pObject3d)->SetColor(r,g,b); } UpdateAllViews(NULL); } } void CMeshDoc::OnUpdateMeshColorChoose(CCmdUI* pCmdUI) { pCmdUI->Enable(m_SceneGraph.NbObject() > 0); }